/*******************************************************************************
 * AlbumArtistView.cpp
 *
 * Copyright (c) 2013, Varuna L Amachi. All rights reserved.
 *
 * This program/library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This program/library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 * MA 02110-1301  USA
 ******************************************************************************/

#include <QModelIndexList>
#include <QItemSelectionModel>
#include <QMessageBox>
#include <QVBoxLayout>
#include <QSplitter>
#include <QHeaderView>
#include <QLabel>

#include <common/RatingDelegate.h>
#include <core/workers/DbCommandHandler.h>
#include <core/manager/T.h>
#include <QContextMenuEvent>


#include "AudioBrowserView.h"


using namespace GreenChilli;
using namespace AudioBrowser;

QString AudioBrowserView::COMPONENT_ID = "GreeChilli::Std::AudioBrowser";
QString AudioBrowserView::COMPONENT_NAME = QObject::tr( "Audio Browser" );

AudioBrowserView::AudioBrowserView(QWidget *parent) :
    GreenChilli::ChilliComponent(parent),
    m_filtering( false )
{
    m_allTracks = new QList< Tanyatu::Model::StoredAudio *>();
    m_allAlbums = new QList< Tanyatu::Model::AlbumInfo *>();
    setupUi();
    setupActions();
    setupConnections();
    reloadTracks();
    reloadAlbums();
}


void AudioBrowserView::setupUi()
{
    m_artistView = new QTreeView( this );
    m_artists = new Tanyatu::Component::ArtistItemModel( 3, this );
    m_artistProxy = new ArtistSortFilter();
    m_artistProxy->setSourceModel( m_artists);
    m_artistView->setModel( m_artistProxy );
    m_artistView->setItemDelegate( new Common::RatingDelegate( 2, this ));
    m_artistView->setSortingEnabled( true );
    m_artistView->setWordWrap( false );
    m_artistView->setAutoScroll( true );
    m_artistView->header()->setResizeMode( 0, QHeaderView::Stretch );
    m_artistView->setColumnWidth( 1, 48 );
    m_artistView->setColumnWidth( 2, 16 );
    m_artistView->header()->setStretchLastSection( false );
    m_artistView->setFont( QFont( m_artistView->font().defaultFamily(), 8 ));
    m_artistView->setSelectionMode( QAbstractItemView::ExtendedSelection );
    m_artistView->setSelectionBehavior( QAbstractItemView::SelectRows );
    m_artistView->setFocusPolicy( Qt::WheelFocus );
    m_artistView->setEditTriggers( QAbstractItemView::CurrentChanged );
    m_artistView->setAlternatingRowColors(true);
    m_artistView->setContextMenuPolicy( Qt::ActionsContextMenu );

    m_albumView = new QTreeView( this );
    m_albums = new Tanyatu::Component::AlbumItemModel( 4, this );
    m_albumProxy = new AlbumSortFilter();
    m_albumProxy->setSourceModel( m_albums );
    m_albumView->setModel( m_albumProxy );
    m_albumView->setItemDelegate( new Common::RatingDelegate( 3, this ));
    m_albumView->setSortingEnabled( true );
    m_albumView->setWordWrap( false );
    m_albumView->setAutoScroll( true );
    m_albumView->header()->setResizeMode( 1, QHeaderView::Stretch );
    m_albumView->header()->setResizeMode( 2, QHeaderView::Stretch );
    m_albumView->setColumnWidth( 3, 16 );
    m_albumView->header()->setStretchLastSection( false );
    m_albumView->hideColumn( 0 );
    m_albumView->setFont( QFont( m_albumView->font().defaultFamily(), 8 ));
    m_albumView->setSelectionMode( QAbstractItemView::ExtendedSelection );
    m_albumView->setSelectionBehavior( QAbstractItemView::SelectRows );
    m_albumView->setFocusPolicy( Qt::WheelFocus );
    m_albumView->setEditTriggers( QAbstractItemView::CurrentChanged );
    m_albumView->setAlternatingRowColors(true);
    m_albumView->setContextMenuPolicy( Qt::ActionsContextMenu );

    m_trackView = new QTreeView( this );
    m_tracks = new TrackModel( 5, this );
    m_trackProxy = new BrowserTrackSortFilter();
    m_trackProxy->setSourceModel( m_tracks );
    m_trackView->setModel( m_trackProxy );
    m_trackView->setItemDelegate( new Common::RatingDelegate( 4, this ));
    m_trackView->setSortingEnabled( true );
    m_trackView->setWordWrap( false );
    m_trackView->setAutoScroll( true );
    m_trackView->header()->setResizeMode( 1, QHeaderView::Stretch );
    m_trackView->header()->setResizeMode( 2, QHeaderView::Stretch );
    m_trackView->header()->setResizeMode( 3, QHeaderView::Stretch );
    m_trackView->setColumnWidth( 3, 16 );
    m_trackView->header()->setStretchLastSection( false );
    m_trackView->hideColumn( 0 );
    m_trackView->setFont( QFont( m_trackView->font().defaultFamily(), 8 ));
    m_trackView->setSelectionMode( QAbstractItemView::ExtendedSelection );
    m_trackView->setSelectionBehavior( QAbstractItemView::SelectRows );
    m_trackView->setFocusPolicy( Qt::WheelFocus );
    m_trackView->setEditTriggers( QAbstractItemView::CurrentChanged );
    m_trackView->setAlternatingRowColors(true);
    m_trackView->setContextMenuPolicy( Qt::ActionsContextMenu );

    QHBoxLayout *filterLayout = new QHBoxLayout();
    m_filterBox = new Tanyatu::Gui::SearchBox( this );
    filterLayout->addWidget( new QLabel( tr( "Filter" ), this ));
    filterLayout->addWidget( m_filterBox );

    QSplitter *upper = new QSplitter( this );
    upper->addWidget( m_artistView );
    upper->addWidget( m_albumView );

    QSplitter *main = new QSplitter( Qt::Vertical, this );
    main->addWidget( upper );
    main->addWidget( m_trackView );

    QVBoxLayout *mainLayout = new QVBoxLayout();
    mainLayout->addLayout( filterLayout );
    mainLayout->addWidget( main );

    this->setLayout( mainLayout );
}


void AudioBrowserView::setupActions()
{
    m_actPlayArtist = new QAction( tr( "Play" ), this );
    m_actPlayAlbum = new QAction( tr( "Play" ), this );
    m_actPlayTracks = new QAction( tr( "Play" ), this );

    m_actDeleteArtist = new QAction( tr( "Delete Artist(s)" ), this );
    m_actDeleteAlbum = new QAction( tr( "Delete Album(s)" ), this );
    m_actDeleteTrack = new QAction( tr( "Delete Track(s)" ), this );

    m_artistView->addAction( m_actPlayArtist );
    m_artistView->addAction( m_actDeleteArtist );

    m_albumView->addAction( m_actPlayAlbum );
    m_albumView->addAction( m_actDeleteAlbum );

    m_trackView->addAction( m_actPlayTracks );
    m_trackView->addAction( m_actDeleteTrack );

    QList< Tanyatu::Model::ArtistInfo * > *artists =
            new QList< Tanyatu::Model::ArtistInfo *>();
    AUDIO_MANAGER()->allArtist( *artists );
    m_artists->setArtistList( artists );
}


void AudioBrowserView::selectRow( QTreeView *view, int row )
{
    if( view->model()->rowCount() > row ) {
        QItemSelectionModel *selection = view->selectionModel();
        QAbstractItemModel *model = view->model();
        selection->select( QItemSelection (
                                model->index ( row, 0 ),
                                model->index ( row, model->columnCount() - 1 )),
                            QItemSelectionModel::Select );
    }
}

void AudioBrowserView::reloadAlbums()
{
    clearAlbumModel();
    if( m_allAlbums ) m_allAlbums->clear();
    AUDIO_MANAGER()->allAlbums( *m_allAlbums );
    m_artistProxy->invalidate();
    m_albumProxy->invalidate();
    m_trackProxy->invalidate();
}


void AudioBrowserView::reloadTracks()
{
    clearTrackModel();
    if( m_allTracks ) m_allTracks->clear();
    AUDIO_LIB()->allItems( *m_allTracks );
    m_artistProxy->invalidate();
    m_albumProxy->invalidate();
    m_trackProxy->invalidate();
}


void AudioBrowserView::reloadArtists()
{
    QList< Tanyatu::Model::ArtistInfo * > *allArtists  =
            new QList< Tanyatu::Model::ArtistInfo *>();
    AUDIO_MANAGER()->allArtist( *allArtists  );

    QList< Tanyatu::Model::AlbumInfo *> *albums =
            new QList< Tanyatu::Model::AlbumInfo *>();
    m_artists->setArtistList( allArtists );
    m_artistProxy->invalidate();
    m_albumProxy->invalidate();
    m_trackProxy->invalidate();
    if( ! allArtists->isEmpty() ) {
        AUDIO_MANAGER()->albumsFromArtist(
                    allArtists->at( 0 )->name(), *albums );
        selectRow( m_artistView, 0 );
        if( ! albums->isEmpty() ) {
            m_albums->setAlbumList( albums );
            selectRow( m_albumView, 0 );
            onAlbumSelected();
        }
        else {
            delete albums;
            clearModels();
        }
    }
    else {
        m_artists->clear();
    }
}


QString AudioBrowserView::componentId() const
{
    return COMPONENT_ID;
}


QString AudioBrowserView::componentName() const
{
    return COMPONENT_NAME;
}


const QIcon* AudioBrowserView::icon() const
{
    return 0;
}


AudioBrowserView::~AudioBrowserView()
{
    if( ! m_filtering ) {
        delete m_allAlbums;
        delete m_allTracks;
    }
}


void AudioBrowserView::onArtistAdded( Tanyatu::Model::ArtistInfo *artist )
{
    if( artist ) {
        reloadArtists();
    }
}


void AudioBrowserView::onAlbumAdded( Tanyatu::Model::AlbumInfo *album )
{
    if( album ) {
        reloadAlbums();
    }
}


void AudioBrowserView::onArtistRemoved( QString artist )
{
    QString *artistName = new QString( artist );
    reloadArtists();
    DBCMD_HANDLER()->addCmd( DBCMD_CODE::Cmd_RemoveArtist,
                             static_cast< void *>( artistName ));
}


void AudioBrowserView::onAlbumRemoved( QString artistName, QString albumName )
{
    QString *albumId = new QString( Tanyatu::Model::AlbumInfo::getAlbumIdFrom(
                                        artistName, albumName ));
    reloadAlbums();
    DBCMD_HANDLER()->addCmd( DBCMD_CODE::Cmd_RemoveAlbum,
                             static_cast< void *>( albumId ));
}


void AudioBrowserView::onArtistInfoChanged( Tanyatu::Model::ArtistInfo *artist )
{
    if( artist ) {
        DBCMD_HANDLER()->addCmd( DBCMD_CODE::Cmd_UpdateArtist,
                                 static_cast< void *>( artist ));
    }
}


void AudioBrowserView::onAlbumInfoChanged( Tanyatu::Model::AlbumInfo *album )
{
    if( album ) {
        DBCMD_HANDLER()->addCmd( DBCMD_CODE::Cmd_UpdateAlbum,
                                 static_cast< void *>( album ));
    }
}


void AudioBrowserView::onTrackChanged()
{
    if( this->isVisible() ) {
        this->update();
    }
}

void AudioBrowserView::trackRemovedFromLibrary()
{
    reloadTracks();
}


void AudioBrowserView::onRemoveArtistAction()
{
    if( DBCMD_HANDLER()->hasPendingTasks() ) {
        QMessageBox::warning( this,
                              tr( "Unable process request" ),
                              tr( "GreenChilli is busy processing other "
                                  "library operations and hence cannot "
                                  "process any removal requests. "
                                  " Please try later." ));
        return;
    }
    QMessageBox::StandardButton button = QMessageBox::question(
                this,
                tr( "Confirm Artist Deletion" ),
                tr( "This operation will remove artist information and all the "
                    "audio tracks related to those artists from library. "
                    " do you want to continue?"),
                QMessageBox::Cancel | QMessageBox::Ok );
    if( button & QMessageBox::Ok ) {
        QModelIndexList indices =
                m_artistView->selectionModel()->selectedRows( 0 );
        if( ! indices.isEmpty() ) {
            QList< QString > *trackIds = 0;
            foreach( const QModelIndex &index, indices ) {
                trackIds = new QList< QString >();
                QString artistName = index.data().toString();
                if( AUDIO_MANAGER()->tracksFromArtist( artistName, *trackIds )){
                    AUDIO_LIB()->remove( *trackIds );
                    DBCMD_HANDLER()->addCmd(DBCMD_CODE::Cmd_RemoveTracksFromLib,
                                             static_cast< void *>( trackIds ));
                }
                else {
                    AUDIO_MANAGER()->removeArtist( artistName );
                }
            }
        }
    }
}


void AudioBrowserView::onRemoveAlbumAction()
{
    if( DBCMD_HANDLER()->hasPendingTasks() ) {
        QMessageBox::warning( this,
                              tr( "Unable process request" ),
                              tr( "GreenChilli is busy processing other "
                                  "library operations and hence cannot "
                                  "process any removal requests. "
                                  " Please try later." ));
        return;
    }
    QMessageBox::StandardButton button = QMessageBox::question(
                this,
                tr( "Confirm Album Deletion" ),
                tr( "This operation will remove album information and all the "
                    "audio tracks related to those albums from library. "
                    " do you want to continue?"),
                QMessageBox::Cancel | QMessageBox::Ok );
    if( button & QMessageBox::Ok ) {
        QModelIndexList indices =
                m_albumView->selectionModel()->selectedRows( 0 );
        if( ! indices.isEmpty() ) {
            QList< QString > *trackIds = 0;
            foreach( const QModelIndex &index, indices ) {
                trackIds = new QList< QString >();
                if( AUDIO_MANAGER()->tracksFromAlbum( index.data().toString(),
                                                      *trackIds )) {
                    AUDIO_LIB()->remove( *trackIds );
                    DBCMD_HANDLER()->addCmd(DBCMD_CODE::Cmd_RemoveTracksFromLib,
                                             static_cast< void *>( trackIds ));
                }
                else {
                    AUDIO_MANAGER()->removeAlbum( index.data().toString() );
                }
            }
        }
    }
}


void AudioBrowserView::onRemoveTrackAction()
{
    if( DBCMD_HANDLER()->hasPendingTasks() ) {
        QMessageBox::warning( this,
                              tr( "Unable process request" ),
                              tr( "GreenChilli is busy processing other "
                                  "library operations and hence cannot "
                                  "process any removal requests. "
                                  " Please try later." ));
        return;
    }
    QMessageBox::StandardButton button = QMessageBox::question(
                this,
                tr( "Confirm Album Deletion" ),
                tr( "This operation will remove audio track(s) from audio "
                    "library do you want to continue?"),
                QMessageBox::Cancel | QMessageBox::Ok );
    if( button & QMessageBox::Ok ) {
        QModelIndexList indices =
                m_trackView->selectionModel()->selectedRows( 0 );
        if( ! indices.isEmpty() ) {
            QList< QString >* trackIds = new QList< QString >();
            foreach( const QModelIndex &index, indices ) {
                trackIds->append( index.data().toString() );
            }
            AUDIO_LIB()->remove( *trackIds );
            DBCMD_HANDLER()->addCmd( DBCMD_CODE::Cmd_RemoveTracksFromLib,
                                     trackIds );
            update();
        }
    }
}


void AudioBrowserView::onLibraryCleared()
{
    clearModels();
    m_artists->clear();
    update();
}


void AudioBrowserView::onArtistSelected()
{
    QModelIndexList selection = m_artistView->selectionModel()->selectedRows(
                0 );
    if( ! selection.isEmpty() ) {
        QList< Tanyatu::Model::AlbumInfo *> *albums =
                new QList< Tanyatu::Model::AlbumInfo *>();
        foreach( const QModelIndex &index, selection ) {
            AUDIO_MANAGER()->albumsFromArtist( index.data().toString(),
                                               *albums );
        }
        if( ! albums->empty() ) {
            // A::L::L
            clearModels();
            m_albums->setAlbumList( albums );
            m_albumView->selectAll();
//            selectRow( m_albumView, 0 );
            onAlbumSelected();
        }
        else {
            delete albums;
        }
    }
}


void AudioBrowserView::onAlbumSelected()
{
    QModelIndexList selection = m_albumView->selectionModel()->selectedRows(
                0 );
    if( ! selection.isEmpty() ) {
        QList< QString > trackIds;
        foreach( const QModelIndex &index, selection ) {
            AUDIO_MANAGER()->tracksFromAlbum(
                        index.data().toString(), trackIds );
        }
        if( ! trackIds.empty() ) {
            QList< Tanyatu::Model::StoredAudio *> *tracks =
                    new QList< Tanyatu::Model::StoredAudio *>();
            AUDIO_LIB()->items( trackIds, *tracks );
            // A::L::L
            if( m_tracks->getTrackList() != m_allTracks ) {
                m_tracks->clear();
            }
            m_tracks->setTrackList( tracks );
        }
    }
}


void AudioBrowserView::onEnqueueArtistTracks()
{
    QModelIndexList selection = m_artistView->selectionModel()->selectedRows(
                0 );
    if( ! selection.isEmpty() ) {
        QList< QString > trackIds;
        foreach( const QModelIndex &index, selection ) {
            AUDIO_MANAGER()->tracksFromArtist( index.data().toString(),
                                               trackIds );
        }
        QList< Tanyatu::Model::MediaItem *> tracksOut;
        AUDIO_LIB()->items( trackIds, tracksOut );
        int playIndex = PLAYLIST()->numberOfItems();
        PLAYLIST()->addItems( tracksOut );
        if( playIndex != PLAYLIST()->numberOfItems() ) {
            PLAYLIST()->selectIndex( playIndex );
        }
    }
}


void AudioBrowserView::onEnqueueAlbumTracks()
{
    QModelIndexList selection = m_albumView->selectionModel()->selectedRows(
                0 );
    if( ! selection.isEmpty() ) {
        QList< QString > trackIds;
        foreach( const QModelIndex &index, selection ) {
            AUDIO_MANAGER()->tracksFromAlbum( index.data().toString(),
                                               trackIds );
        }
        QList< Tanyatu::Model::MediaItem *> tracksOut;
        AUDIO_LIB()->items( trackIds, tracksOut );
        int playIndex = PLAYLIST()->numberOfItems();
        PLAYLIST()->addItems( tracksOut );
        PLAYLIST()->selectIndex( playIndex );
    }
}


void AudioBrowserView::onEnqueueTracks()
{
    QModelIndexList selection = m_trackView->selectionModel()->selectedRows(
                0 );
    if( ! selection.isEmpty() ) {
        if( selection.size() == 1 ) {
            Tanyatu::Model::StoredAudio *track = AUDIO_LIB()->item(
                        selection.at( 0 ).data().toString() )    ;
            PLAYLIST()->addItem( track, true );
        }
        else {
            QList< QString > trackIds;
            foreach( const QModelIndex &index, selection ) {
                trackIds.append( index.data().toString() );
            }
            QList< Tanyatu::Model::MediaItem *> tracksOut;
            AUDIO_LIB()->items( trackIds, tracksOut );

            PLAYLIST()->addItems( tracksOut );

        }
    }
}

void AudioBrowserView::addPlayFromArtist()
{
    int playIndex = PLAYLIST()->numberOfItems();
    onEnqueueArtistTracks();
    if( playIndex != PLAYLIST()->numberOfItems() ) {
        PLAYLIST()->selectIndex( playIndex );
    }
}

void AudioBrowserView::addPlayFromAlbum()
{
    int playIndex = PLAYLIST()->numberOfItems();
    onEnqueueAlbumTracks();
    if( playIndex != PLAYLIST()->numberOfItems() ) {
        PLAYLIST()->selectIndex( playIndex );
    }
}

void AudioBrowserView::addPlayTracks()
{
    int playIndex = PLAYLIST()->numberOfItems();
    onEnqueueTracks();
    if( playIndex != PLAYLIST()->numberOfItems() ) {
        PLAYLIST()->selectIndex( playIndex );
    }
}


void AudioBrowserView::onFilterBoxEntry()
{
    QString text = m_filterBox->text();
    if( text.isEmpty() ) {
        m_filtering = false;
        m_tracks->clear( false );
        m_albums->clear( false );
    }
    else if( ! m_filtering ) {
        m_filtering = true;
        clearModels();
        m_tracks->setTrackList( m_allTracks );
        m_albums->setAlbumList( m_allAlbums );
    }
    m_artistProxy->setExpression( text );
    m_albumProxy->setExpression( text );
    m_trackProxy->setExpression( text );
}

void AudioBrowserView::onFilterBoxComitted()
{
    m_trackView->selectAll();
    onEnqueueTracks();
}


void AudioBrowserView::setupConnections()
{
    connect( AUDIO_MANAGER(),
             SIGNAL( artistAdded( Tanyatu::Model::ArtistInfo * )),
             this,
             SLOT( onArtistAdded( Tanyatu::Model::ArtistInfo * )));

    connect( AUDIO_MANAGER(),
             SIGNAL( albumAdded( Tanyatu::Model::AlbumInfo * )),
             this,
             SLOT( onAlbumAdded( Tanyatu::Model::AlbumInfo * )));

    connect( AUDIO_MANAGER(),
             SIGNAL( artistRemoved( QString )),
             this,
             SLOT( onArtistRemoved( QString )));

    connect( AUDIO_MANAGER(),
             SIGNAL( albumRemoved( QString,QString )),
             this,
             SLOT( onAlbumRemoved( QString, QString )));

    connect( AUDIO_MANAGER(),
             SIGNAL( artistRemoved( QString )),
             this,
             SLOT( onArtistSelected() ));

    connect( AUDIO_MANAGER(),
             SIGNAL( albumRemoved( QString, QString )),
             this,
             SLOT( onAlbumSelected() ));

    connect( AUDIO_MANAGER(),
             SIGNAL( artistModified( Tanyatu::Model::ArtistInfo * )),
             this,
             SLOT( onArtistInfoChanged( Tanyatu::Model::ArtistInfo * )));

    connect( AUDIO_MANAGER(),
             SIGNAL( albumModified( Tanyatu::Model::AlbumInfo * )),
             this,
             SLOT( onAlbumInfoChanged( Tanyatu::Model::AlbumInfo * )));

    connect( AUDIO_LIB(),
             SIGNAL( itemChanged( Tanyatu::Model::StoredAudio * )),
             this,
             SLOT( onTrackChanged() ));

    connect( AUDIO_LIB(),
             SIGNAL( aboutToClear() ) ,
             this,
             SLOT( onLibraryCleared() ));

    connect( AUDIO_LIB(),
             SIGNAL( itemRemoved( QString )),
             this,
             SLOT( trackRemovedFromLibrary() ));

    connect( m_actPlayArtist,
             SIGNAL( triggered() ),
             this,
             SLOT( onEnqueueArtistTracks() ));

    connect( m_actPlayAlbum,
             SIGNAL( triggered() ),
             this,
             SLOT( onEnqueueAlbumTracks() ));

    connect( m_actPlayTracks,
             SIGNAL( triggered() ),
             this,
             SLOT( onEnqueueTracks() ));

    connect( m_actDeleteArtist,
             SIGNAL( triggered() ),
             this,
             SLOT( onRemoveArtistAction() ));

    connect( m_actDeleteAlbum,
             SIGNAL( triggered() ),
             this,
             SLOT( onRemoveAlbumAction() ));

    connect( m_actDeleteTrack,
             SIGNAL( triggered() ),
             this,
             SLOT( onRemoveTrackAction() ));

    connect( m_artistView->selectionModel(),
             SIGNAL( selectionChanged( QItemSelection, QItemSelection )),
             this,
             SLOT( onArtistSelected() ));

    connect( m_artistView,
             SIGNAL( activated( QModelIndex )),
             this,
             SLOT( addPlayFromArtist() ));

    connect( m_albumView->selectionModel(),
             SIGNAL( selectionChanged( QItemSelection, QItemSelection )),
             this,
             SLOT( onAlbumSelected() ));

    connect( m_albumView,
             SIGNAL( activated( QModelIndex )),
             this,
             SLOT( addPlayFromAlbum() ));

    connect( m_trackView,
             SIGNAL( activated( QModelIndex )),
             this,
             SLOT( addPlayTracks() ));

    connect( m_filterBox,
             SIGNAL( textChanged( QString )),
             this,
             SLOT( onFilterBoxEntry() ));

    connect( m_filterBox,
             SIGNAL( returnPressed() ),
             this,
             SLOT( onFilterBoxComitted() ));
}
